package com.jy.modules.cims.common.sysUtils;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jy.modules.cims.common.CimsConstant;
import com.jy.modules.cims.common.exception.CimsExceptionConstant;

public class FileUtils {
	private static Logger logger = LoggerFactory.getLogger(FileUtils.class);

	/**
	 * @description 删除目录（文件夹）以及目录下的文件
	 * @author shengzhoutao
	 * @param sPath
	 *            被删除目录的文件路径
	 * @return 目录删除成功返回true，否则返回false
	 */
	public static boolean deleteDirectory(String sPath) {
		// 如果sPath不以文件分隔符结尾，自动添加文件分隔符
		if (!sPath.endsWith(File.separator)) {
			sPath = sPath + File.separator;
		}

		File dirFile = new File(sPath);
		// 如果dir对应的文件不存在，或者不是一个目录，则退出
		if (!dirFile.exists() || !dirFile.isDirectory()) {
			return false;
		}

		boolean flag = true;
		// 删除文件夹下的所有文件(包括子目录)
		File[] files = dirFile.listFiles();
		if(null == files){
			return false;
		}
		for (int i = 0; i < files.length; i++) {
			// 删除子文件
			if (files[i].isFile()) {
				flag = deleteFile(files[i].getAbsolutePath());
				if (!flag)
					break;
			} // 删除子目录
			else {
				flag = deleteDirectory(files[i].getAbsolutePath());
				if (!flag)
					break;
			}
		}

		if (!flag) {
			return false;
		}

		// 删除当前目录
		if (dirFile.delete()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @description 删除单个文件
	 * @author shengzhoutao
	 * @param sPath
	 *            被删除文件的文件名
	 * @return 单个文件删除成功返回true，否则返回false
	 */
	public static boolean deleteFile(String sPath) {
		boolean flag = false;
		File file = new File(sPath);
		// 路径为文件且不为空则进行删除
		if (file.isFile() && file.exists()) {
			flag = file.delete();
		}
		return flag;
	}

	/**
	 * @description 创建文件和父文件夹
	 * @author shengzhoutao
	 * @param destFileName
	 *            要创建文件和父文件夹
	 * @return 创建文件和父文件夹成功返回true，文件存在或者创建创建文件和父文件夹失败返回false
	 */
	public static boolean createFile(String destFileName) {
		File file = new File(destFileName);
		if (file.exists()) {
			return false;
		}

		if (destFileName.endsWith(File.separator)) {
			return false;
		}

		if (!file.getParentFile().exists()) {
			if (!file.getParentFile().mkdirs()) {
				return false;
			}
		}

		// 创建目标文件
		try {
			if (file.createNewFile()) {
				return true;
			} else {
				return false;
			}
		} catch (IOException e) {
			e.printStackTrace();
			logger.error(CimsExceptionConstant.FILE_CREATEERROR, destFileName);
			return false;
		}
	}

	/**
	 * @description 创建目录
	 * @author shengzhoutao
	 * @param destDirName
	 *            要创建文件夹
	 * @return 创建文件夹成功返回true，文件存在或者创建创建文件夹失败返回false
	 */
	public static boolean createDir(String destDirName) {
		File dir = new File(destDirName);
		if (dir.exists()) {
			return false;
		}

		// 创建单个目录
		if (dir.mkdirs()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @description 创建临时文件的文件名前缀、后缀及文件所在的目录
	 * @author shengzhoutao
	 * @param prefix
	 *            文件名前缀
	 * @param suffix
	 *            后缀及文件
	 * @param dirName
	 *            文件所在的目录
	 * @return 返回规范化的绝对路径
	 */
	public static String createTempFile(String prefix, String suffix, String dirName) {
		File tempFile = null;
		try {
			if (dirName == null) {
				// 在默认文件夹下创建临时文件
				tempFile = File.createTempFile(prefix, suffix);
				return tempFile.getCanonicalPath();
			} else {
				File dir = new File(dirName);
				// 如果临时文件所在目录不存在，首先创建
				if (!dir.exists()) {
					if (!createDir(dirName)) {
						return null;
					}
				}
				tempFile = File.createTempFile(prefix, suffix, dir);
				return tempFile.getCanonicalPath();
			}
		} catch (IOException e) {
			e.printStackTrace();
			logger.debug(e.getMessage());
			return null;
		}
	}

	/**
	 * @description 读取并解析带有分割符的文件
	 * @author zhuwenbin
	 * @param fileFullName
	 *            文件名称
	 * @param regex
	 *            分隔符
	 * @param column
	 *            列数
	 * @return
	 */
	public static List<String[]> analyRegexFile(String fileFullName, String regex, int column) {
		File analyFile = null;
		List<String[]> analyList = null;
		BufferedReader bufferedreader = null;
		InputStreamReader insReader = null;
		FileInputStream fileins = null;
		try {
			analyFile = new File(fileFullName);
			// 判断文件是否存在
			if (analyFile.exists()) {
				fileins = new FileInputStream(analyFile);
				insReader = new InputStreamReader(fileins, CimsConstant.HYL_FILECHARSET);
				bufferedreader = new BufferedReader(insReader);
				String readerline = null;
				analyList = new ArrayList<String[]>();
				// 读取并按照分割符解析
				while (bufferedreader.ready()) {
					readerline = bufferedreader.readLine();
					if (readerline == null || "".equals(readerline)) {
						continue;
					}
					String[] splitStr = readerline.split(regex, column);
					analyList.add(splitStr);
				}
			} else {
				logger.error(CimsExceptionConstant.FILE_NOTEXIST, fileFullName);
			}
		} catch (Exception e) {
			logger.error(CimsExceptionConstant.FILE_ANALYERROR, fileFullName);
		} finally {
			if (bufferedreader != null) {
				try {
					bufferedreader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (insReader != null) {
				try {
					insReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (fileins != null) {
				try {
					fileins.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return analyList;

	}

	/**
	 * @description 读取并解析带有分割符的文件
	 * @author zhuwenbin
	 * @param fileFullName
	 *            文件名称
	 * @param regex
	 *            分隔符
	 * @param column
	 *            列数
	 * @return
	 */
	public static List<String[]> analyRegexByStream(InputStream in, String regex, int column) {
		List<String[]> analyList = null;
		BufferedReader bufferedreader = null;
		InputStreamReader insReader = null;
		try {
			// 判断文件是否存在
			insReader = new InputStreamReader(in, CimsConstant.HYL_FILECHARSET);
			bufferedreader = new BufferedReader(insReader);
			String readerline = null;
			analyList = new ArrayList<String[]>();
			// 读取并按照分割符解析
			while (bufferedreader.ready()) {
				readerline = bufferedreader.readLine();
				if (readerline == null || "".equals(readerline)) {
					continue;
				}
				String[] splitStr = readerline.split(regex, column);
				analyList.add(splitStr);
			}
		} catch (Exception e) {
			logger.error(CimsExceptionConstant.FILE_ANALYERROR);
		} finally {
			if (bufferedreader != null) {
				try {
					bufferedreader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (insReader != null) {
				try {
					insReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		}
		return analyList;

	}

	/**
	 * @description 写文件方法，生成带分割符文件
	 * @author zhuwenbin
	 * @param fileFullName
	 *            文件名称
	 * @param listStr
	 *            字符串列表
	 * @return
	 */
	public static boolean writeFile(String fileFullName, List<StringBuffer> listStr) {

		File file = null;
		FileOutputStream fileos = null;
		PrintWriter writer = null;
		boolean flag = false;
		try {
			file = new File(fileFullName);
			if (file.createNewFile()) {
				fileos = new FileOutputStream(file);
				writer = new PrintWriter(fileos);
				for (StringBuffer strbuffer : listStr) {
					strbuffer.append(System.getProperty(CimsConstant.LINE_SEPARATOR));
					writer.write(strbuffer.toString());
					writer.flush();
				}
				flag = true;
			} else {
				logger.error(CimsExceptionConstant.FILE_CREATEERROR, fileFullName);
			}
		} catch (IOException e) {
			logger.error(CimsExceptionConstant.FILE_CREATEERROR, fileFullName);
		} finally {
			if (writer != null) {
				writer.close();
			}
			if (fileos != null) {
				try {
					fileos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		return flag;
	}

	/**
	 * @description 将字符串写入输出流
	 * @author zhuwenbin
	 * @param listStr
	 *            字符串列表
	 * @param os
	 *            输出流
	 * @return
	 */
	public static boolean writeFile(List<StringBuffer> listStr, OutputStream os) {
		PrintWriter writer = null;
		boolean flag = false;
		try {
			writer = new PrintWriter(os);
			for (StringBuffer strbuffer : listStr) {
				strbuffer.append(System.getProperty(CimsConstant.LINE_SEPARATOR));
				writer.write(strbuffer.toString());
				writer.flush();
			}
			flag = true;
		} finally {
			if (writer != null) {
				writer.close();
			}
		}

		return flag;
	}

	/**
	 * @description 从网络Url中下载文件
	 * @author shengzhoutao
	 * @param urlStr
	 *            要下载的网络资源URL地址
	 * @param fileName
	 *            在本地生成的新文件名
	 * @param savePath
	 *            下载到本地文件目录
	 * @throws IOException
	 */
	public static void downLoadFromUrl(String urlStr, String fileName, String savePath) throws IOException {
		//logger.info("要下载的网络资源URL地址:" + urlStr);
		//logger.info("在本地生成的新文件名:" + fileName);
		//logger.info("下载到本地文件目录:" + savePath);

		InputStream inputStream = null;
		FileOutputStream fileOutputStream = null;
		URL url = null;
		HttpURLConnection httpURLConnection = null;
		try {
			// 文件保存位置
			File saveDir = new File(savePath);
			if (!saveDir.exists()) {
				boolean flag = saveDir.mkdirs();
				if (!flag) {
					throw new RuntimeException(java.text.MessageFormat.format("创建下载到本地文件目录[{0}]不成功：", savePath));
				}
			}

			File file = new File(SimpleStringUtils.append(saveDir, File.separator, fileName));
			fileOutputStream = new FileOutputStream(file);

			url = new URL(urlStr);
			httpURLConnection = (HttpURLConnection) url.openConnection();
			// 设置超时间
			httpURLConnection.setConnectTimeout(CimsConstant.HTTP_URL_CONNECTION_CONNECT_TIMEOUT);
			// 防止屏蔽程序抓取而返回403错误
			httpURLConnection.setRequestProperty(CimsConstant.HTTP_URL_REQUEST_PROPERTY_KEY, CimsConstant.HTTP_URL_REQUEST_PROPERTY_VALUE);

			// 得到输入流
			inputStream = httpURLConnection.getInputStream();
			copyInputStream2OutputStream(inputStream, fileOutputStream, true);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("从网络Url中下载文件异常：", e);
		} finally {
			if (fileOutputStream != null) {
				fileOutputStream.close();
			}
			if (inputStream != null) {
				inputStream.close();
			}
			if (httpURLConnection != null) {
				httpURLConnection.disconnect();
			}
		}
	}

	/**
	 * @description 从输入流中获取字节数组
	 * @author shengzhoutao
	 * @param inputStream
	 * @return
	 * @throws IOException
	 */
	public static byte[] readInputStream(InputStream inputStream) throws IOException {
		byte[] buffer = new byte[1024];
		int len = 0;
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		while ((len = inputStream.read(buffer)) != -1) {
			byteArrayOutputStream.write(buffer, 0, len);
		}

		byteArrayOutputStream.close();
		return byteArrayOutputStream.toByteArray();
	}

	/**
	 * 复制流 到 前端浏览器
	 * 
	 * @param inputStream
	 *            源文件输入流
	 * @param outputStream
	 *            输出流
	 * @param flush
	 * @return
	 */
	public static void copyInputStream2OutputStream(InputStream inputStream, OutputStream outputStream, boolean flush) {
		int bytes;

		byte[] buffer = new byte[1024];
		try {
			while ((bytes = inputStream.read(buffer)) != -1) {
				if (bytes == 0) {
					bytes = inputStream.read();
					if (bytes < 0) {
						break;
					}
					outputStream.write(bytes);
					if (flush) {
						outputStream.flush();
					}
				}
				outputStream.write(buffer, 0, bytes);
				if (flush) {
					outputStream.flush();
				}
			}
		} catch (IOException e) {
			throw new RuntimeException("IOException caught while copying.", e);
		}
	}
	/**
	 * 获取指定文件的byte[]
	 * @author zhangmi
	 * @date  2016年12月22日
	 * @param filePath
	 * @return
	 */
	public static byte[] getBytes(String filePath) throws Exception{  
        byte[] buffer = null;  
        FileInputStream fis = null;
        ByteArrayOutputStream bos = null;
        try {  
            File file = new File(filePath);  
            fis = new FileInputStream(file);  
            bos = new ByteArrayOutputStream(1000);  
            byte[] b = new byte[1000];  
            int n;  
            while ((n = fis.read(b)) != -1) {  
                bos.write(b, 0, n);  
            }  
          
            buffer = bos.toByteArray();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
            throw new FileNotFoundException("获取不到指定文件！");
        } catch (IOException e) {  
            e.printStackTrace();  
            throw new FileNotFoundException("获取文件IO流失败！");
        }finally{
        	if(fis!=null)
        	  fis.close();
        	if(bos!=null)
              bos.close();  
        }
        return buffer;  
    }
	
	/**
	 * 获取文件大小
	 * @author zhangmi
	 * @date  2017年1月4日
	 * @param path
	 * @return
	 * @throws Exception
	 */
	public static long getFileSize(String path) throws Exception{
		File f= new File(path);  
	    if(f.isFile()){
	    	return f.length();
	    }else{
	    	return 0;
	    }
	}
}
